home *** CD-ROM | disk | FTP | other *** search
- /**\
- |**| =====================================================================
- |**|
- |**| Adjust Layout.c
- |**|
- |**| This file contains the calls that this sample needs to make
- |**| the QuickDraw GX shell work correctly.
- |**|
- |**| QuickDraw GX Libraries Used:
- |**| "ColorLibrary.c", "FontLibrary.c", "GraphicsDebugLibrary.c",
- |**| "LayoutLibrary.c", "ShapeLibrary.c", and "TransformLibrary.c".
- |**|
- |**| 6/96 bob Updated #includes to support changed GX Library names.
- |**| Updated the copyright date.
- |**|
- |**| ©1990 - 1996 Apple Computer, Inc.
- |**| All rights reserved.
- |**|
- |**| =====================================================================
- \**/
-
-
- #include "QDGX shell.h"
- #include <GXLayout.h>
- #include "LayoutLibrary.h"
-
-
- // Convenient constants for simplifying the code
-
- #define withFactor {0, -ff(4)/30}
- #define crossFactor {0, fixed1/3}
- #define glyphA 36
- #define glyphE (glyphA + 'E' - 'A')
- #define glyphJ (glyphA + 'J' - 'A')
- #define glyphK (glyphA + 'K' - 'A')
- #define glyphN (glyphA + 'N' - 'A')
- #define glyphU (glyphA + 'U' - 'A')
- #define glyphV (glyphA + 'V' - 'A')
- #define glyphW (glyphA + 'W' - 'A')
- #define glyphY (glyphW + 2)
- #define nAdjustments 3
- #define nSubstitutions 4
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| PROTOTYPES
- |**| ---------------------------------------------------------------------
- \**/
-
- // funtions required by shell
-
- void DoSetup (void);
- void DoDraw (WindowPtr wind, Boolean updating);
- OSErr DoCreateNew (void);
- void DoDispose (WindowPtr wind);
- void DoIdle (WindowPtr wind);
- void DoTeardown (void);
- void DoClick (WindowPtr wind, Point p);
-
- // private functions
-
- OSErr DoWindowInit (WindowPtr wind);
- void CreateSampleImage (WindowPtr wind);
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| ENUMS
- |**| ---------------------------------------------------------------------
- \**/
- enum { rWindResource = 128 };
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| GLOBALS
- |**| ---------------------------------------------------------------------
- \**/
- // If gDebugging = TRUE, graphics library errors and notices will be posted. This
- // functionality will only work with the "debugging" version of QuickDraw GX.
- // If the debugging version is not installed, nothing bad will happen, but these
- // functions will not work.
-
- Boolean gDebugging = true;
-
- // Set "gGiveMeValidation" to TRUE if you want receive run-time validation.
-
- Boolean gGiveMeValidation = true;
-
-
- // gGraphicsHeapSize sets the size of the graphics heap created by calling the
- // GXNewGraphicsClient routine in main () within QuickDraw GX shell.c. You can determine
- // the amount of graphics heap required by using GraphicsBug. I'm giving it 600K,
- // since we need abunch if we have several windows open.
-
- long gGraphicsHeapSize = 600;
-
- // gOurPrintingOverrideUPP is a universal proc pointer for our printing event
- // override. This is so that our override can be native PowerPC code if necessary.
-
- GXPrintingEventUPP gOurPrintingOverrideUPP;
-
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoSetup()
- |**| Here's where we initialize any global variables our application needs.
- |**| We have only one at this time -- the universal proc pointer for
- |**| our printing override.
- |**| ---------------------------------------------------------------------
- \**/
- void DoSetup (void)
- { // Initialize our printing event override UPP
- gOurPrintingOverrideUPP = NewGXPrintingEventProc(MyPrintingEventOverride);
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoDraw()
- |**| Draw the contents of the window. The first parameter is the window
- |**| to draw, and the second parameter is true if we're updating an existing
- |**| image. If that's the case, we don't want to change anything, but
- |**| just draw what's already there.
- |**| ---------------------------------------------------------------------
- \**/
- void DoDraw (WindowPtr wind, Boolean updating)
- {
- #pragma unused (updating)
- GXDrawShape (GetDocShape(wind));
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoCreateNew()
- |**| This routine is called when a window needs to be created.
- |**| ---------------------------------------------------------------------
- \**/
- OSErr DoCreateNew (void)
- {
- OSErr err = noErr;
- WindowPtr wind;
-
- // Get and create our window from the resource fork
-
- wind = GetNewWindow(rWindResource, nil, (WindowPtr)-1L);
-
- // Attach a default gxViewPort to it, create and iInitialize our
- // private data for it, and add a sample image to its page shape.
-
- if ( wind == NULL )
- return (MemError());
-
- GXIgnoreGraphicsNotice(transform_already_set);
- SetDefaultViewPort(GXNewWindowViewPort(wind));
- GXPopGraphicsNotice();
-
- err = DoWindowInit(wind);
- if ( err != noErr )
- return err;
-
- CreateSampleImage(wind);
- return err;
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoDispose()
- |**| This routine is called when a window needs to be disposed of.
- |**| ---------------------------------------------------------------------
- \**/
- void DoDispose (WindowPtr wind)
- {
- TH_Doc doc;
-
- // You should always dispose of your GX graphics objects before tossing your window.
- // Why? It's generally good form and this approach guarantees that everything is
- // disposed. If you had not disposed of everything, the call to DisposeWindow should
- // dispose of the objects. If you are running the debugging version of QuickDraw GX
- // with notices set, you will receive a notice that you had not disposed of everything.
- // You can turn notices on in this file by setting gDebugging = TRUE (above).
-
- if ( wind != NULL )
- {
- doc = (TH_Doc)GetWRefCon(wind); // Remember, this is where we stored our private data.
- GXDisposeShape(GetDocShape(wind)); // Dispose of this doc's shape.
- GXDisposeJob(GetDocJob(wind)); // Dispose of this doc's print job.
- DisposHandle((Handle) doc); // Dispose of our private data.
- DisposeWindow(wind); // Dispose of the window.
- }
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoIdle()
- |**| This routine is called to do things while idling through the event loop.
- |**| ---------------------------------------------------------------------
- \**/
- void DoIdle (WindowPtr wind)
- {
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoTeardown()
- |**| This routine is called just before we quit to remove anything
- |**| persistent that might have been setup by DoSetup().
- |**| ---------------------------------------------------------------------
- \**/
- void DoTeardown (void)
- {
- DisposeRoutineDescriptor(gOurPrintingOverrideUPP);
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoClick()
- |**| ---------------------------------------------------------------------
- \**/
- void DoClick(WindowPtr window, Point p)
- {
- }
-
-
-
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoWindowInit()
- |**| In this function we create and initialize the the private document
- |**| structure for a new window. This structure contains the print job and
- |**| the shape which is drawn in the window. We store this data in a handle
- |**| and hang it off the window's refCon field for easy retrieval. By doing
- |**| this, rather than using globals, we can create many windows containing
- |**| unique print jobs and shapes.
- |**| ---------------------------------------------------------------------
- \**/
- OSErr DoWindowInit (WindowPtr wind)
- {
- OSErr err = noErr;
- gxJob docJob;
- gxShape docPage;
- TH_Doc windDoc;
-
-
- // Create the page shape. We set the unique items attribute to make sure that each item
- // added to the picture has a unique reference. If this attribute was not set, we would
- // not see all copies of anything we add to the shape multiple times -- we'd just see
- // the last version added.
-
- docPage = GXNewShape(gxPictureType);
- GXSetShapeAttributes(docPage, (GXGetShapeAttributes(docPage) | gxUniqueItemsShape));
-
-
- // Create a print job for this document. This will be the same as the system default until
- // the user goes through the dialogs for Page Setup or Print…
-
- err = GXNewJob(&docJob);
-
-
- // If there are no errors, create a handle the size of our document structure and store
- // the print job and page shape in it. Store the handle in the window's refCon field so
- // that we can get at it. (Note that the utility routines "GetDocJob" and "GetDocShape"
- // can be used to do this easily.
-
- if ( err == noErr )
- {
- windDoc = (TH_Doc) NewHandleClear(sizeof(T_Doc));
-
- if ( windDoc == NULL )
- err = MemError();
- else
- {
- (*windDoc)->docJob = docJob;
- (*windDoc)->docPage = docPage;
- SetWRefCon(wind, (long) windDoc);
- }
-
- // Now install our application override for PrintingEvent so that we can
- // support the new movable-modal printing dialog boxes.
-
- GXInstallApplicationOverride(docJob, gxPrintingEventMsg, gOurPrintingOverrideUPP);
-
- }
-
- return err;
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| CreateSampleImage()
- |**| This function creates primitive shapes and adds them to the window's page shape.
- |**| ---------------------------------------------------------------------
- \**/
- void CreateSampleImage (WindowPtr wind)
- {
- Rect ourWindowRect = wind->portRect; // the rectangle for this window
- // in QuickDraw coordinates
- gxShape layout; // the layout shape we're building
- gxShape thePage; // the picture shape for our window
- gxRunControls controls; // run controls for the layout
- gxLayoutOptions layoutOptions; // options for our layout
- StyleRunOverrides overrides; // structure defined in layout library.h
- // and used in several library calls to
- // make working with style runs easier
- gxStyle glyphStyles[3]; // array of three different styles for
- // glyphs we use
- // Here's the text of the three runs
-
- char *text1 = "Office";
- char *text2 = "AWAY AND SOME ";
- char *text3 = "JUNK.";
-
- char *textRuns[3]; // and the array to hold them
-
- short level0 = 0; // We have to pass levels by address,
- // so here's a variable to hold one
- short textLengths[3]; // array of text lengths for GXNewLayout
- short totalLength; // sum of the text lengths
-
- // The "glyphX" values are #define'd at the top of this file. There are four
- // values in each set -- the glyph code of the first glyph, the glyph code of the
- // second glyph, how much with-stream kerning to apply and how much cross-stream
- // kerning to apply. We're kerning with the pairs A-W, A-Y and W-A here.
- // Normally you would _not_ hard-code glyph codes because they can change from font
- // to font, but this is a demonstration, not a shipping application. Try this on
- // some non-Roman fonts, or some where the glyph codes for the ASCII characters aren't
- // the same as their ASCII value, and you'll see strange results.
-
- gxKerningAdjustment adjustments[nAdjustments] =
- {{glyphA, glyphW, withFactor, crossFactor},
- {glyphA, glyphY, withFactor, crossFactor},
- {glyphW, glyphA, withFactor, crossFactor}};
-
- // The gxGlyphSubstitution array lets us substitute one glyph for another by
- // glyph code. Again taking the liberty of assuming glyph codes for Times Roman,
- // this set substitutes the second glyph in each pair for the first when the layout
- // shape is drawn.
-
- gxGlyphSubstitution substitutions[nSubstitutions] =
- {{glyphJ, glyphW},
- {glyphU, glyphA},
- {glyphN, glyphV},
- {glyphK, glyphE}};
-
- gxPoint posn; // The position for the layout shape
-
-
- // OK, now to work. First, initialize the textRuns array.
-
- textRuns[0] = text1;
- textRuns[1] = text2;
- textRuns[2] = text3;
-
-
- // Next, initialize the textLengths array. MyStrLength is in this file to avoid linking
- // in a huge ANSI library.
-
- textLengths[0] = MyStrLength (text1);
- textLengths[1] = MyStrLength (text2);
- textLengths[2] = MyStrLength (text3);
-
-
- // Now add them all up to get the total length.
-
- totalLength = textLengths[0] + textLengths[1] + textLengths[2];
-
-
- // Make default gxLayoutOptions, gxRunControls and StyleRunOverrides structures.
- // The library routines which initialize these default structures may be found in
- // layout library.c.
-
- InitializeLayoutOptions (&layoutOptions);
- InitializeRunControls (&controls);
- InitializeStyleRunOverrides (&overrides);
-
- // Position the layout half way down the left edge of the window. Set
- // the layout's width to the window's width and set the flushness to 1/2, this
- // will cause the layout to center in the window.
-
- layoutOptions.width = ff(ourWindowRect.right - ourWindowRect.left);
- layoutOptions.flush = fract1/2; // fract1 is defined in math types.h
-
- posn.x = 0;
- posn.y = ff((ourWindowRect.bottom - ourWindowRect.top) / 2);
-
-
- // Initialize the style runs. The first one (#0) is 60 point Times Roman.
- // We create the style with NewLayoutStyle, found in layout library.c
-
- glyphStyles[0] = NewLayoutStyle(
- (char *) "\pHoefler Text", // The gxFontName for this style
- ff(60), // the text size in fixed point
- 0, // gxTextAttribute (none for us)
- &controls, // run controls (none for this style)
- nil, // run features (none right now)
- 0, // count of run features (no run features == 0)
- nil); // style run overrides (none right now)
-
- // Now we create the next style. We reuse the controls and style run overrides
- // structures, so now we set those up for the second (#1) style.
-
- // Initialize the run controls:
- // Set the cross stream shift to 30 to raise the text 30 points,
- // and the with stream shift to -4 to move the text 4 points
- // closer together than normal kerning would move it.
-
- controls.crossStreamShift = ff(30);
- controls.beforeWithStreamShift = ff(-2);
- controls.afterWithStreamShift = ff(-2);
-
- // Now set up the style run overrides:
- // Set up the kerning adjustments to the array we already created, and
- // put the count in. nAdjustments is #define'd in Adjust Layout Sample.h.
-
- overrides.kerningAdjustments = adjustments;
- overrides.kerningAdjustmentsCount = nAdjustments;
-
- // We're ready to create the second style -- 30 pt. Times Roman with kerning adjustments
-
- glyphStyles[1] = NewLayoutStyle(
- (char *) "\pTimes Roman", // the gxFontName
- ff(30), // the text size
- 0, // no text attributes
- &controls, // our run controls we initialized
- nil, // no run features
- 0, // so the run feature count is zero
- &overrides); // and our style run overrides (kerning adjustments)
-
- // For the third style, we reset the run controls and kerning adjustments, but now
- // set the glyph substitutions talked about earlier.
-
- controls.crossStreamShift = 0; // default
-
- overrides.kerningAdjustments = nil; // default
- overrides.kerningAdjustmentsCount = 0; // default
-
- overrides.glyphSubstitutions = substitutions; // our glyph subs array
- overrides.glyphSubstitutionsCount = nSubstitutions; // our glyph subs count
-
-
- // Finally, create the third style -- 60 pt. Times Roman with glyph substitutions
-
- glyphStyles[2] = NewLayoutStyle(
- (char *) "\pTimes Roman", // the font name
- ff(60), // the text size
- 0, // no text attributes
- &controls, // our run controls (default again)
- nil, // no run features
- 0, // so the run feature count is zero
- &overrides); // and our style run overrides (glyph subs)
-
- // Now we can build the layout and add it to our picture shape
-
- layout = GXNewLayout(
- 3, // count of text runs
- textLengths, // array of lengths of each run
- (void *) textRuns, // array of pointers to the text
- 3, // count of style runs
- textLengths, // array of the byte length of each style run
- glyphStyles, // the array of styles we've been constructing
- 1, // the number of levels in this layout
- &totalLength, // the length of text this level applies to (all of it)
- &level0, // array of next levels (this could be nil, too)
- &layoutOptions, // our layout options (centered, flush 1/2, etc.)
- &posn); // the position of the layout shape
-
-
- // Retrieve the page shape so we can add to it.
-
- thePage = GetDocShape(wind);
-
- // Add the layout to the window's picture shape. AddToShape is in shape library.c.
-
- AddToShape(thePage, layout);
-
- // We're done with the layout and styles, so get rid of them
-
- GXDisposeShape(layout);
- GXDisposeStyle(glyphStyles[0]);
- GXDisposeStyle(glyphStyles[1]);
- GXDisposeStyle(glyphStyles[2]);
-
-
- // Invalidate the window's portRect so that everything gets updated.
-
- SetPort(wind);
- InvalRect(&ourWindowRect);
- }
-
-